package com.ourhours.message.rpc.service.impl;

import com.alibaba.fastjson.JSON;
import com.ourhours.global.response.ApiResponse;
import com.ourhours.global.response.ApiResponseBuilder;
import com.ourhours.message.api.SmsCodeRpcService;
import com.ourhours.message.constant.ConstantMQ;
import com.ourhours.message.domain.SmsSend;
import com.ourhours.message.domain.Supplier;
import com.ourhours.message.domain.Template;
import com.ourhours.message.enums.ApiResponseCode;
import com.ourhours.message.enums.MessageTypeEnum;
import com.ourhours.message.enums.SmsTypeEnum;
import com.ourhours.message.exception.MessageException;
import com.ourhours.message.request.SmsCodeRequest;
import com.ourhours.message.response.MmsBaseResponseCode;
import com.ourhours.message.service.SmsSendService;
import com.ourhours.message.service.TemplateService;
import com.ourhours.message.service.wrapper.SmsWrapper;
import com.ourhours.message.service.wrapper.SupplierWrapper;
import com.ourhours.redismq.Message;
import com.ourhours.redismq.RedisMQMessageSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;


import java.util.Date;
import java.util.Random;

@Service("smsCodeRpcService")
public class SmsCodeRpcServiceImpl implements SmsCodeRpcService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SmsCodeRpcServiceImpl.class);

    @Autowired
    SmsSendService smsSendService;

    @Autowired
    SupplierWrapper supplierWrapper;

    @Autowired
    JmsTemplate jmsTemplate;

    @Autowired
    RedisMQMessageSender messageSender;

    @Autowired
    TemplateService templateService;

    @Autowired
    SmsWrapper smsWrapper;



    /**
     * 发送验证码
     */
    @Override
    public ApiResponse<Boolean> sendVerifyCode(SmsCodeRequest smsCodeRequest) {
        try{
            long startTime = System.currentTimeMillis();
            String phone = smsCodeRequest.getPhone();
            Long vendorId = smsCodeRequest.getVendorId();

            //从缓存中获取运营商信息
            Supplier supplier = supplierWrapper.findSupplierWithCache(smsCodeRequest.getVendorId(), MessageTypeEnum.SMS.getCode());
            if(supplier==null){
                LOGGER.error("获取营运商信息失败,参数:{},结果:{}",smsCodeRequest,supplier);
                throw new MessageException("根据vendorId=" + smsCodeRequest.getVendorId() + ",查询推送供应商表数据为空！");
            }
            String code =  (int)((Math.random()*9+1)*100000)+"";
            Template template = templateService.getTemplateByType(smsCodeRequest.getVerifyTypeEnum().getCode(),smsCodeRequest.getVendorId());
            String content = template.getContent().replace("${1}", code);

            //接受消息，保存数据库
            SmsSend smsSend = new SmsSend();
            smsSend.setPhone(smsCodeRequest.getPhone());
            smsSend.setVendorId(smsCodeRequest.getVendorId());
            smsSend.setSmsType(smsCodeRequest.getVerifyTypeEnum().getCode());
            smsSend.setCode(code);
            smsSend.setContent(content);
            smsSend.setCreateTime(new Date());
            smsSend.setUpdateTime(new Date());
            smsSend.setCreateUser(phone);
            smsSend.setUpdateUser(phone);
            smsSend.setSupplierId(supplier.getId());

            smsSend.setStatus(0);
            Boolean status = smsSendService.insert(smsSend);
            long endTime = System.currentTimeMillis();
            Long redisResult = messageSender.put(new Message(ConstantMQ.smsSendMQ, JSON.toJSONString(smsSend)));
            if(redisResult==null){
                //报警
                smsWrapper.smsAlarmInfo(vendorId);
                //直接发
                boolean result = smsSendService.sendMessage(smsSend);
                if(result){
                    smsSend.setStatus(1);
                    smsSendService.updateById(smsSend);
                    LOGGER.info("发送短信成功：参数:{},{},{}, 结果:{}",phone,vendorId,content,status);
                    return ApiResponseBuilder.buildSuccess(true);
                }else{
                    smsSend.setStatus(2);
                    smsSendService.updateById(smsSend);
                    LOGGER.error("发送短信失败：参数:{},{},{}, 结果:{}",phone,vendorId,content,status);
                    return ApiResponseBuilder.buildError(MmsBaseResponseCode.SEND_PHONE_CODE_ERROR.code,MmsBaseResponseCode.SEND_PHONE_CODE_ERROR.msg);
                }
            }

            LOGGER.info("发送MQ成功：参数:{},结果:{},所用时间:{}",smsCodeRequest,status,endTime-startTime);
            return ApiResponseBuilder.buildSuccess(true);
        }catch (MessageException me){
            LOGGER.error("发送短信失败：参数:{},异常:{}",smsCodeRequest,me);
            return ApiResponseBuilder.buildError(MmsBaseResponseCode.SEND_PHONE_CODE_ERROR.code,MmsBaseResponseCode.SEND_PHONE_CODE_ERROR.msg);
        }catch (Exception e){
            LOGGER.error("发送短信失败：参数:{},异常:{}",smsCodeRequest,e);
            return ApiResponseBuilder.buildError(MmsBaseResponseCode.SEND_PHONE_CODE_ERROR.code,MmsBaseResponseCode.SEND_PHONE_CODE_ERROR.msg);
        }

    }

    /**
     * 验证码进行验证
     */
    @Override
    public ApiResponse<Boolean> verifyPhoneCode(SmsCodeRequest smsCodeRequest){
        try{
            SmsSend smsSend = new SmsSend();
            smsSend.setPhone(smsCodeRequest.getPhone());
            smsSend.setVendorId(smsCodeRequest.getVendorId());
            smsSend.setCode(smsCodeRequest.getPhoneCode());
            smsSend.setSmsType(smsCodeRequest.getVerifyTypeEnum().getCode());
            Boolean result = smsSendService.verifyPhoneVacode(smsSend);
            LOGGER.info("验证手机验证码成功,参数:{},结果:{}", smsCodeRequest,result);
            return ApiResponseBuilder.buildSuccess(result);
        }catch(MessageException e){
            LOGGER.error("验证手机验证码异常,参数:{},结果:{}", smsCodeRequest,e);
            return ApiResponseBuilder.buildError(e.getCode(), e.getMessage());
        }catch (Exception e1){
            LOGGER.error("验证手机验证码异常：{}", e1);
            return ApiResponseBuilder.buildError(ApiResponseCode.ERROR.getCode(), e1.getMessage());
        }
    }



}
